package com.um.jdy.app.shop.manager;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.um.jdy.app.shop.entity.dto.*;
import com.um.jdy.app.shop.entity.vo.*;
import com.um.jdy.common.shop.entity.po.Courier;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.shop.service.CourierService;
import com.um.jdy.common.commons.utils.Kuaidi100Util;
import com.um.jdy.common.member.entity.po.Address;
import com.um.jdy.common.member.service.AddressService;
import com.um.jdy.common.member.service.MemberUserService;
import com.um.jdy.common.shop.code.ShopAftersaleCode;
import com.um.jdy.common.shop.code.ShopOrderCode;
import com.um.jdy.common.shop.entity.po.*;
import com.um.jdy.common.shop.entity.vo.OrderAftersaleDynamicVO;
import com.um.jdy.common.shop.enums.AftersaleEnum;
import com.um.jdy.common.shop.enums.OrderEnum;
import com.um.jdy.common.shop.service.*;
import com.um.jdy.common.system.entity.po.Param;
import com.um.jdy.common.system.service.ParamService;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.utils.condition.ConditionBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @Title
 * @Description
 * @Author renjunwei
 * @Date 2023/5/22 10:37
 */
@Slf4j
@Service
public class ShopAftersaleManager {

    @Autowired
    ShopOrderService shopOrderService;

    @Autowired
    OrderGoodsService orderGoodsService;

    @Autowired
    MemberUserService memberUserService;

    @Autowired
    OrderAftersaleService orderAftersaleService;

    @Autowired
    OrderGoodsAftersaleService orderGoodsAftersaleService;

    @Autowired
    OrderAftersaleDynamicService orderAftersaleDynamicService;

    @Autowired
    CourierService courierService;

    @Autowired
    ParamService paramService;

    @Autowired
    AddressService addressService;

    /**
     * 分页查询售后
     * @param dto
     * @return
     */
    public Page<ShopAftersaleItemVO> getPage(AftersalePageDTO dto){
        Page<ShopAftersaleItemVO> page = new Page(dto);

        Map<String, String> condition = ConditionBuilder.create()
                .put("a.member_user_id", memberUserService.get().getMemberUserId())
                .put("a.com_id", memberUserService.get().getComId())
                .put("a.status", dto.getStatus())
                .putLike("g.goods_name", dto.getName())
                .build();
        page = orderAftersaleService.getCMSViewModelPageBySqlName(page, "get_aftersale_page", "get_aftersale_count",
                ShopAftersaleItemVO.class, condition.keySet().toArray(new String[0]), condition.values().toArray(new String[0]),
                new ArrayList(), new String[]{}, new String[]{});
        page.getResult().stream().forEach(item -> item.setGoods(getGoodsList(item.getShopOrderAftersaleId())));
        return page;
    }

    /**
     * 查询售后详情
     * @return
     */
    public AftersaleDetailVO get(String shopOrderAftersaleId){
        OrderAftersale aftersale = orderAftersaleService.getEntity(new String[]{"member_user_id", "shop_order_aftersale_id"},
                new String[]{memberUserService.get().getMemberUserId(), shopOrderAftersaleId});
        if(null == aftersale){
            throw new ServiceException(ShopAftersaleCode.AftersaleNotExist);
        }
        Order order = shopOrderService.getRealEntity(aftersale.getShopOrderId());

        AftersaleDetailVO detail = BeanUtil.toBean(aftersale, AftersaleDetailVO.class);
        detail.setOrderNo(order.getOrderNo());
        detail.setGoods(getGoodsList(shopOrderAftersaleId));
        return detail;
    }

    /**
     * 查询售后商品列表
     *
     * @param shopOrderAftersaleId
     * @return
     */
    public List<AftersaleGoodsItemVO> getGoodsList(String shopOrderAftersaleId) {
        return shopOrderService.getViewModelList("get_aftersale_goods", AftersaleGoodsItemVO.class, new Object[]{shopOrderAftersaleId,shopOrderService.getComId()});
    }

    /**
     * 申请售后
     * @return
     */
    @Transactional
    public OrderAftersale apply(AddAftersaleDTO dto, String id) {
        Order order = shopOrderService.getEntity(dto.getShopOrderId());
        if (null == order || StrUtil.equals(order.getStatus(), OrderEnum.Status.UnPay.name()) ||
                StrUtil.equals(order.getStatus(), OrderEnum.Status.UnComment.name()) ||
                StrUtil.equals(order.getStatus(), OrderEnum.Status.Cancelled.name()) ||
                StrUtil.equals(order.getStatus(), OrderEnum.Status.Completed.name())) {
            throw new ServiceException("申请售后失败，该订单"+ OrderEnum.Status.valueOf(order.getStatus()).getValue()+"！");
        }

        OrderAftersale orderAftersale = this.getBaseOrderAftersale(order, dto);
        if(StrUtil.isNotEmpty(id)){
            orderAftersale.setShopOrderAftersaleId(id);
        }
        orderAftersale.setIsDelete("0");
        orderAftersaleService.save(orderAftersale);

        Integer amount = 0;
        for (String orderGoodsId : dto.getOrderGoodsIds()) {
            OrderGoods orderGoods = orderGoodsService.getEntity(orderGoodsId);
            if (null == orderGoods || !StrUtil.equals(orderGoods.getShopOrderId(), order.getShopOrderId())) {
                throw new ServiceException(ShopOrderCode.OrderGoodsNotExist);
            }
            if(!AftersaleEnum.Type.Refund.name().equals(dto.getType()) && YesOrNo.No.name().equals(orderGoods.getIsBack())){
                throw new ServiceException("不支持退换货");
            }

            OrderGoodsAftersale orderGoodsAftersale = orderGoodsAftersaleService.
                    getEntityBySqlName("get_effective_aftersale_goods",new String[]{orderGoodsId,orderGoods.getComId()});
            if(null != orderGoodsAftersale){
                throw new ServiceException("已申请售后");
                // throw new ServiceException(orderGoods.getGoodsName()+"已申请售后");
            }


            if(StrUtil.isNotEmpty(orderGoods.getMarketActivityId())){
                //自动售后赠品
                OrderGoods giftOrderGoods = orderGoodsService.getEntity(new String[]{"shop_order_id", "market_activity_id", "type"},
                        new String[]{orderGoods.getShopOrderId(), orderGoods.getMarketActivityId(), OrderEnum.GoodsType.FullReduce.name()});
                if(null != giftOrderGoods){
                    //校验一下赠品是否已售后
                    OrderGoodsAftersale giftOrderGoodsAftersale = orderGoodsAftersaleService.
                            getEntityBySqlName("get_effective_aftersale_goods",new String[]{giftOrderGoods.getShopOrderGoodsId(),giftOrderGoods.getComId()});
                    if(null == giftOrderGoodsAftersale){
                        orderGoodsAftersaleService.save(this.getBaseOrderGoodsAftersale(orderAftersale, giftOrderGoods));
                    }
                }
            }

            orderGoodsAftersale = this.getBaseOrderGoodsAftersale(orderAftersale, orderGoods);
            // 换货 TODO 目前不用换规格
//            if(StringUtil.equals(type,AftersaleOrderType.BARTER.getKey())){
//                Map option = dao.queryMap(TableName.MALL_GOODS_OPTION,item.get("update_shop_goods_option_id"));
//                if(null == option || StringUtil.toInt(orderGoods.get("num")) > StringUtil.toInt(option.get("stock"))){
//                    throw new ServiceException(ReturnObject.CODE_2,option.get("title")+"库存不足");
//                }
//                orderGoodsAftersale.put("update_shop_goods_option_id",item.get("update_shop_goods_option_id"));
//                orderGoodsAftersale.put("update_spec",option.get("title"));
//            }
            orderGoodsAftersaleService.save(orderGoodsAftersale);

            amount = NumberUtil.add(amount, orderGoods.getPayment()).intValue();
        }

        // List<OrderGoods> orderGoods = orderGoodsService.getList("shop_order_id", dto.getShopOrderId());
        // List<OrderGoodsAftersale> aftersaleGoods = orderGoodsAftersaleService.getList("shop_order_aftersale_id", orderAftersale.getShopOrderAftersaleId());

        // // 未发货的全部退款加上运费
        // if(orderGoods.size() == aftersaleGoods.size() && (StrUtil.equals(order.getStatus(), OrderEnum.Status.UnSend.name()) ||
        //         StrUtil.equals(order.getStatus(), OrderEnum.Status.UnGroup.name()))){
        //     amount = NumberUtil.add(amount, order.getDeliveryPrice()).intValue();
        // }

        orderAftersale.setAmount(amount);
        orderAftersaleService.update(orderAftersale);

        this.saveDynamic(orderAftersale);

        return orderAftersale;
    }

    private OrderAftersale getBaseOrderAftersale(Order order, AddAftersaleDTO dto) {
        OrderAftersale orderAftersale = new OrderAftersale();
        orderAftersale.setMemberUserId(order.getMemberUserId());
        orderAftersale.setShopOrderId(order.getShopOrderId());
        orderAftersale.setAftersaleNo(order.getOrderNo());
        orderAftersale.setProvince(order.getProvince());
        orderAftersale.setCity(order.getCity());
        orderAftersale.setArea(order.getArea());
        orderAftersale.setAddress(order.getAddress());
        orderAftersale.setLinkman(order.getLinkman());
        orderAftersale.setPhone(order.getPhone());
        orderAftersale.setReason(dto.getReason());
        orderAftersale.setRemark(dto.getRemark());
        orderAftersale.setThumbs(dto.getThumbs());
        orderAftersale.setType(dto.getType());
        orderAftersale.setStatus(AftersaleEnum.Status.UnReview.name());
        orderAftersale.setCreateTime(DateUtil.date());
        if(StrUtil.isNotEmpty(dto.getMemberAddressId()) && AftersaleEnum.Type.Exchange.name().equals(dto.getType())){
            Address address = addressService.getEntity(dto.getMemberAddressId());
            if(null == address){
                throw new ServiceException(ShopOrderCode.AddressNotExist);
            }
            orderAftersale.setProvince(address.getProvince());
            orderAftersale.setCity(address.getCity());
            orderAftersale.setArea(address.getArea());
            orderAftersale.setAddress(address.getAddress());
            orderAftersale.setLinkman(address.getName());
            orderAftersale.setPhone(address.getPhone());
        }
        return orderAftersale;
    }

    private OrderGoodsAftersale getBaseOrderGoodsAftersale(OrderAftersale orderAftersale, OrderGoods orderGoods) {
        OrderGoodsAftersale orderGoodsAftersale = new OrderGoodsAftersale();
        orderGoodsAftersale.setShopOrderAftersaleId(orderAftersale.getShopOrderAftersaleId());
        orderGoodsAftersale.setShopOrderGoodsId(orderGoods.getShopOrderGoodsId());
        orderGoodsAftersale.setShopGoodsId(orderGoods.getShopGoodsId());
        orderGoodsAftersale.setMemberUserId(orderAftersale.getMemberUserId());
        orderGoodsAftersale.setCreateTime(DateUtil.date());
        return orderGoodsAftersale;
    }

    private void saveDynamic(OrderAftersale aftersale){
        String title = "";
        switch (AftersaleEnum.Status.valueOf(aftersale.getStatus())){
            case UnReview:
                title = "您的"+ AftersaleEnum.Type.valueOf(aftersale.getType()).getValue()+"售后申请已提交，等待商家审批";
                break;

            case UnSendBack:
                title = "商家已同意您的"+ AftersaleEnum.Type.valueOf(aftersale.getType()).getValue()+"售后申请，请尽快寄回商品";
                break;

            case UnSend:
                title = "您已寄回商品，等待商家收货后即寄出商品";
                break;

            case UnReceive:
                title = "商家已寄出换货商品";
                break;

            case Refund:
                title = "您已寄回商品，等待商家收货后即可退款";
                break;

            case Reject:
                title = "商家已拒绝您的"+ AftersaleEnum.Type.valueOf(aftersale.getType()).getValue()+"售后申请，您可以修改原因后重新提交";
                break;

            case Cancelled:
                title = "您的"+ AftersaleEnum.Type.valueOf(aftersale.getType()).getValue()+"售后申请已取消";
                break;

            case Completed:
                if(StrUtil.equals(aftersale.getType(), AftersaleEnum.Type.Exchange.name())){
                    title = "您已确认收到换货商品，售后已完成";
                }else{
                    title = "商家已操作退款，售后已完成";
                }
                break;
        }

        OrderAftersaleDynamic dynamic = new OrderAftersaleDynamic();
        dynamic.setShopOrderAftersaleId(aftersale.getShopOrderAftersaleId());
        dynamic.setTitle(title);
        dynamic.setCreateTime(DateUtil.date());
        orderAftersaleDynamicService.save(dynamic);
    }

    /**
     * 修改售后
     * @param shopOrderAftersaleId
     * @param dto
     * @return
     */
    @Transactional
    public void updateApply(String shopOrderAftersaleId, AddAftersaleDTO dto) {
        orderAftersaleService.delete("shop_order_aftersale_id", shopOrderAftersaleId);
        orderGoodsAftersaleService.delete("shop_order_aftersale_id", shopOrderAftersaleId);

        OrderAftersale orderAftersale = this.apply(dto, shopOrderAftersaleId);

        //修改之前的售后动态
        List<OrderAftersaleDynamic> aftersaleDynamicList = orderAftersaleDynamicService.getList(new String[]{"shop_order_aftersale_id"},
                new Object[]{shopOrderAftersaleId});
        for(OrderAftersaleDynamic aftersaleDynamic : aftersaleDynamicList){
            aftersaleDynamic.setShopOrderAftersaleId(orderAftersale.getShopOrderAftersaleId());
            orderAftersaleDynamicService.update(aftersaleDynamic);
        }
    }

    /**
     * 取消售后
     *
     * @param shopOrderAftersaleId
     * @return
     */
    public void cancel(String shopOrderAftersaleId) {
        OrderAftersale orderAftersale = orderAftersaleService.getEntity(shopOrderAftersaleId);
        if (null == orderAftersale || (!StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnReview.name())
                && !StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnSendBack.name()))) {
            throw new ServiceException("取消售后失败，该售后"+ AftersaleEnum.Status.valueOf(orderAftersale.getStatus()).getValue()+"！");
        }

        orderAftersale.setStatus(AftersaleEnum.Status.Cancelled.name());
        orderAftersaleService.update(orderAftersale);

        this.saveDynamic(orderAftersale);
    }

    /**
     * 删除售后
     * @param shopOrderAftersaleId
     * @return
     */
    public void delete(String shopOrderAftersaleId) {
        OrderAftersale orderAftersale = orderAftersaleService.getEntity(shopOrderAftersaleId);
        if (null == orderAftersale || (!StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.Cancelled.name()) &&
                !StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.Completed.name()))) {
            throw new ServiceException("删除失败，该售后"+ AftersaleEnum.Status.valueOf(orderAftersale.getStatus()).getValue()+"！");
        }

        orderAftersale.setUserDelete(YesOrNo.Yes.name());
        orderAftersaleService.update(orderAftersale);
    }

    /**
     * 填写售后
     * @param dto
     * @return
     */
    public void delivery(AftersaleDeliveryDTO dto) {
        OrderAftersale orderAftersale = orderAftersaleService.getEntity(dto.getShopOrderAftersaleId());
        if (null == orderAftersale || !StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnSendBack.name())) {
            throw new ServiceException("填写物流失败，该售后"+ AftersaleEnum.Status.valueOf(orderAftersale.getStatus()).getValue()+"！");
        }

        orderAftersale.setReturnCourier(dto.getCourier());
        orderAftersale.setReturnCourierNo(dto.getCourierNo());
        orderAftersale.setReturnDeliveryTime(DateUtil.date());

        if(StrUtil.equals(orderAftersale.getType(), AftersaleEnum.Type.ReturnRefund.name())){
            orderAftersale.setStatus(AftersaleEnum.Status.Refund.name());
        }else{
            orderAftersale.setStatus(AftersaleEnum.Status.UnSend.name());
        }
        orderAftersaleService.update(orderAftersale);

        this.saveDynamic(orderAftersale);
    }

    /**
     * 确认售后收货
     *
     * @param mallOrderAftersaleId
     * @return
     */
    public void receive(String mallOrderAftersaleId) {
        OrderAftersale orderAftersale = orderAftersaleService.getEntity(mallOrderAftersaleId);
        if (null == orderAftersale || !StrUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnReceive.name())) {
            throw new ServiceException("确认售后收货失败，该售后"+ AftersaleEnum.Status.valueOf(orderAftersale.getStatus()).getValue()+"！");
        }

        orderAftersale.setStatus(AftersaleEnum.Status.Completed.name());
        orderAftersale.setReceivingTime(DateUtil.date());

        this.saveDynamic(orderAftersale);

        orderAftersaleService.update(orderAftersale);
    }

    /**
     * 查询售后物流轨迹
     *
     * @param shopOrderAftersaleId
     * @param isReturn
     * @return
     */
    public Object getExpressTrack(String shopOrderAftersaleId, boolean isReturn) {
        AftersaleDetailVO aftersale = this.get(shopOrderAftersaleId);
        Object expressTrack;
        if(isReturn){
            Courier courier = courierService.getEntity("name", aftersale.getReturnCourier());
            expressTrack = Kuaidi100Util.queryTrack(Optional.ofNullable(courier).orElseGet(Courier::new).getCode(),
                    aftersale.getReturnCourierNo(), aftersale.getReturnPhone());
        }else {
            Courier courier = courierService.getEntity("name", aftersale.getCourier());
            expressTrack = Kuaidi100Util.queryTrack(Optional.ofNullable(courier).orElseGet(Courier::new).getCode(),
                    aftersale.getCourierNo(), aftersale.getPhone());
        }
        return expressTrack;
    }

    /**
     * 查询售后动态
     * @param shopOrderAftersaleId
     * @return
     */
    public List<OrderAftersaleDynamicVO> getDynamicList(String shopOrderAftersaleId){
        List<OrderAftersaleDynamic> list = orderAftersaleDynamicService.getList("shop_order_aftersale_id",
                shopOrderAftersaleId, "create_time", "desc");
        return BeanUtil.copyToList(list, OrderAftersaleDynamicVO.class);
    }

    /**
     * 查询售后原因
     * @return
     */
    public List<String> getReasons(){
        List<Param> list = paramService.getList("path", "shop.AfterSaleReason", "sort_no", "asc");
        return list.stream().map(item -> item.getPValue()).collect(Collectors.toList());
    }
}
